### 7.10 CFI directives

#### 7.10.1 `.cfi_sections` section_list

`.cfi_sections` may be used to specify whether CFI directives should emit `.eh_frame` section and/or `.debug_frame` section. If section_list is `.eh_frame`, `.eh_frame` is emitted, if section_list is `.debug_frame`, `.debug_frame` is emitted. To emit both use `.eh_frame, .debug_frame`. The default if this directive is not used is `.cfi_sections .eh_frame`.

On targets that support compact unwinding tables these can be generated by specifying `.eh_frame_entry` instead of `.eh_frame`.

#### 7.10.2 `.cfi_startproc [simple]`

`.cfi_startproc` is used at the beginning of each function that should have an entry in `.eh_frame`. It initializes some internal data structures. Don't forget to close the function by `.cfi_endproc`.

Unless `.cfi_startproc` is used along with parameter `simple` it also emits some architecture dependent initial CFI instructions.

#### 7.10.3 `.cfi_endproc`

`.cfi_endproc` is used at the end of a function where it closes its unwind entry previously opened by `.cfi_startproc`, and emits it to `.eh_frame`.

#### 7.10.4 `.cfi_personality` encoding`[,` exp`]`

`.cfi_personality` defines personality routine and its encoding. encoding must be a constant determining how the personality should be encoded. If it is 255 (`DW_EH_PE_omit`), second argument is not present, otherwise second argument should be a constant or a symbol name. When using indirect encodings, the symbol provided should be the location where personality can be loaded from, not the personality routine itself. The default after `.cfi_startproc` is `.cfi_personality 0xff`, no personality routine.

#### 7.10.5 `.cfi_personality_id` id

`cfi_personality_id` defines a personality routine by its index as defined in a compact unwinding format. Only valid when generating compact EH frames (i.e. with `.cfi_sections eh_frame_entry`.

#### 7.10.6 `.cfi_fde_data [`opcode1`[, ...]]`

`cfi_fde_data` is used to describe the compact unwind opcodes to be used for the current function. These are emitted inline in the `.eh_frame_entry` section if small enough and there is no LSDA, or in the `.gnu.extab` section otherwise. Only valid when generating compact EH frames (i.e. with `.cfi_sections eh_frame_entry`.

#### 7.10.7 `.cfi_lsda` encoding`[,` exp`]`

`.cfi_lsda` defines LSDA and its encoding. encoding must be a constant determining how the LSDA should be encoded. If it is 255 (`DW_EH_PE_omit`), the second argument is not present, otherwise the second argument should be a constant or a symbol name. The default after `.cfi_startproc` is `.cfi_lsda 0xff`, meaning that no LSDA is present.

#### 7.10.8 `.cfi_inline_lsda` [align]

`.cfi_inline_lsda` marks the start of a LSDA data section and switches to the corresponding `.gnu.extab` section. Must be preceded by a CFI block containing a `.cfi_lsda` directive. Only valid when generating compact EH frames (i.e. with `.cfi_sections eh_frame_entry`.

The table header and unwinding opcodes will be generated at this point, so that they are immediately followed by the LSDA data. The symbol referenced by the `.cfi_lsda` directive should still be defined in case a fallback FDE based encoding is used. The LSDA data is terminated by a section directive.

The optional align argument specifies the alignment required. The alignment is specified as a power of two, as with the `.p2align` directive.

#### 7.10.9 `.cfi_def_cfa` register`,` offset

`.cfi_def_cfa` defines a rule for computing CFA as: take address from register and add offset to it.

#### 7.10.10 `.cfi_def_cfa_register` register

`.cfi_def_cfa_register` modifies a rule for computing CFA. From now on register will be used instead of the old one. Offset remains the same.

#### 7.10.11 `.cfi_def_cfa_offset` offset

`.cfi_def_cfa_offset` modifies a rule for computing CFA. Register remains the same, but offset is new. Note that it is the absolute offset that will be added to a defined register to compute CFA address.

#### 7.10.12 `.cfi_adjust_cfa_offset` offset

Same as `.cfi_def_cfa_offset` but offset is a relative value that is added/substracted from the previous offset.

#### 7.10.13 `.cfi_offset` register`,` offset

Previous value of register is saved at offset offset from CFA.

#### 7.10.14 `.cfi_rel_offset` register`,` offset

Previous value of register is saved at offset offset from the current CFA register. This is transformed to `.cfi_offset` using the known displacement of the CFA register from the CFA. This is often easier to use, because the number will match the code it's annotating.

#### 7.10.15 `.cfi_register` register1`,` register2

Previous value of register1 is saved in register register2.

#### 7.10.16 `.cfi_restore` register

`.cfi_restore` says that the rule for register is now the same as it was at the beginning of the function, after all initial instruction added by `.cfi_startproc` were executed.

#### 7.10.17 `.cfi_undefined` register

From now on the previous value of register can't be restored anymore.

#### 7.10.18 `.cfi_same_value` register

Current value of register is the same like in the previous frame, i.e. no restoration needed.

#### 7.10.19 `.cfi_remember_state`,

First save all current rules for all registers by `.cfi_remember_state`, then totally screw them up by subsequent `.cfi_*` directives and when everything is hopelessly bad, use `.cfi_restore_state` to restore the previous saved state.

#### 7.10.20 `.cfi_return_column` register

Change return column register, i.e. the return address is either directly in register or can be accessed by rules for register.

#### 7.10.21 `.cfi_signal_frame`

Mark current function as signal trampoline.

#### 7.10.22 `.cfi_window_save`

SPARC register window has been saved.

#### 7.10.23 `.cfi_escape` expression[, ...]

Allows the user to add arbitrary bytes to the unwind info. One might use this to add OS-specific CFI opcodes, or generic CFI opcodes that GAS does not yet support.

#### 7.10.24 `.cfi_val_encoded_addr` register`,` encoding`,` label

The current value of register is label. The value of label will be encoded in the output file according to encoding; see the description of `.cfi_personality` for details on this encoding.

The usefulness of equating a register to a fixed label is probably limited to the return address register. Here, it can be useful to mark a code segment that has only one return address which is reached by a direct branch and no copy of the return address exists in memory or another register.